//
//  MemorySafetyExample.swift
//  SwiftCode
//
//  Created by yuhus on 2024/1/8.
//

import Foundation

class MemorySafetyExample: ListViewController {
  override func getItemCount() -> Int {
    data.count
  }
  
  override func getItem(_ indexPath: IndexPath) -> Item {
    data[indexPath.row]
  }
  
  private lazy var data: [Item] = [
    .init(title: "In-Out 参数的访问冲突", description: "函数会对它所有的 in-out 参数保持长期写访问", action: accessConflict),
    .init(title: "In-Out 参数的访问冲突", description: "解决: 显式拷贝一份", action: solveAccessConflict),
    .init(title: "属性的访问冲突", description: "元组的属性访问冲突", action: propertyConflict),
    .init(title: "属性的访问冲突", description: "解决: 改为本地变量而非全局变量，保证结构体属性的重叠访问是安全的", action: solvePropertyConflict),
  ]
}

private var stepSize = 1

private func increment(_ number: inout Int) {
  number += stepSize
  
}

private func accessConflict() {
  // 同时访问0x10073c238，但修改需要独占访问。
  increment(&stepSize)
}

private func solveAccessConflict() {
  // 显式拷贝
  var copyOfStepSize = stepSize
  increment(&copyOfStepSize)
  
  // 更新原来的值
  stepSize = copyOfStepSize
  // stepSize 现在的值是 2
  debugPrint(stepSize)
}

private func balance(_ x: inout Int, _ y: inout Int) {
  let sum = x + y
  x = sum / 2
  y = sum - x
}

private var playerInformation = (health: 10, energy: 20)
private func propertyConflict() {
  debugPrint(#function)
  balance(&playerInformation.health, &playerInformation.energy)
  // 错误：playerInformation 的属性访问冲突
}

/// 改为本地变量而非全局变量，编译器就可以保证这个重叠访问是安全的
private func solvePropertyConflict() {
  debugPrint(#function)
  var playerInformation = (health: 10, energy: 20)
  balance(&playerInformation.health, &playerInformation.energy)
  debugPrint(playerInformation.health, playerInformation.energy)
}
